package br.edu.ufcg.dsc.psoo.mymoney.model.hibernate;

import java.io.Serializable;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.StaleStateException;
import org.hibernate.Transaction;
import org.hibernate.criterion.Restrictions;

import br.edu.ufcg.dsc.psoo.mymoney.controller.exceptions.InvalidGroupException;
import br.edu.ufcg.dsc.psoo.mymoney.model.bean.Group;
import br.edu.ufcg.dsc.psoo.mymoney.model.dao.GroupDAO;

/**
 * Implementa��o de GroupDAO
 * 
 * @author leonardo
 * @version 1.0
 */
public class HibernateGroupDAO implements GroupDAO {

	private Session session;

	public void setSession(Session session) {
		this.session = session;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * br.edu.ufcg.dsc.psoo.model.dao.GroupDAO#create(br.edu.ufcg.dsc.psoo.model
	 * .bean.Group)
	 */
	public Group create(Group group) {

		Transaction tx = session.beginTransaction();
		Serializable saved = session.save(group);
		Group newAccount = (Group) session.get(Group.class, saved);
		tx.commit();

		return newAccount;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * br.edu.ufcg.dsc.psoo.model.dao.GroupDAO#delete(br.edu.ufcg.dsc.psoo.model
	 * .bean.Group)
	 */
	public void delete(Group group) {

		Transaction tx = session.beginTransaction();
		Group deleteMe = (Group) session.get(Group.class, group.getId());
		session.delete(deleteMe);
		tx.commit();

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * br.edu.ufcg.dsc.psoo.model.dao.GroupDAO#load(br.edu.ufcg.dsc.psoo.model
	 * .bean.Group)
	 */
	public Group load(Serializable id) {

		Transaction tx = session.beginTransaction();
		Group bdAccount = (Group) session.get(Group.class, id);
		tx.commit();

		return bdAccount;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * br.edu.ufcg.dsc.psoo.model.dao.GroupDAO#update(br.edu.ufcg.dsc.psoo.model
	 * .bean.Group)
	 */
	public Group update(Group group) throws InvalidGroupException {
		try {
			Transaction tx = session.beginTransaction();
			session.update(group);
			tx.commit();

			return group;
		} catch (StaleStateException e) {
			throw new InvalidGroupException("Invalid group for update!");
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * br.edu.ufcg.dsc.psoo.model.dao.GroupDAO#find(br.edu.ufcg.dsc.psoo.model
	 * .bean.Group)
	 */
	@SuppressWarnings("unchecked")
	public List<Group> find(Group group) {
		// TODO criteria aqui

		Transaction tx = session.beginTransaction();
		Criteria criteria = session.createCriteria(Group.class);
		if (group!=null && group.getAccount()!=null) {
			Criteria subCriteriaAccount = criteria.createCriteria("account");
			if (group.getAccount().getId() !=null) {
				subCriteriaAccount.add(Restrictions.eq("id", group.getAccount().getId()));
			}
			if ((group.getAccount().getUser()!=null) && (group.getAccount().getUser().getId()!=null)) {
				Criteria subSubCriteriaAccountUser = subCriteriaAccount.createCriteria("user");
				subSubCriteriaAccountUser.add(Restrictions.eq("id", group.getAccount().getUser().getId()));
			}
			
			
			
		}
		List<Group> list = (List<Group>) criteria.list();
		tx.commit();

		return list;
	}

	// TODO string exata testar isso
	/*
	 * (non-Javadoc)
	 * 
	 * @see br.edu.ufcg.dsc.psoo.model.dao.GroupDAO#findByName(java.lang.String)
	 */
	@SuppressWarnings("unchecked")
	public List<Group> findByName(String name) {

		Transaction tx = session.beginTransaction();
		Criteria criteria = session.createCriteria(Group.class);
		criteria.add(Restrictions.eq("name", name));
		List<Group> list = (List<Group>) criteria.list();
		tx.commit();
		return list;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see br.edu.ufcg.dsc.psoo.model.dao.GroupDAO#listAll()
	 */
	@SuppressWarnings("unchecked")
	public List<Group> listAll() {

		Transaction tx = session.beginTransaction();
		Criteria criteria = session.createCriteria(Group.class);
		List<Group> list = (List<Group>) criteria.list();
		tx.commit();

		return list;
	}

}
